package com.prothink.threadproject.controller;

import com.prothink.threadproject.common.R;
import com.prothink.threadproject.util.CacheUitl;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.http.ResponseEntity;

import java.io.*;
import java.util.concurrent.ConcurrentHashMap;

@RestController
@CrossOrigin(origins = "http://localhost:8080") // 允许跨域请求
@RequestMapping("/upload") // 指定文件上传的请求路径
public class FileUploadController {

    // 使用 ConcurrentHashMap 作为缓存，存储每个文件的上传进度
    // 这样可以确保多线程下访问是安全的，进度信息与文件名相关联
    private static ConcurrentHashMap<String, Long> progressMap = new ConcurrentHashMap<>();

    /**
     * 文件上传接口
     *
     * @param file 用户上传的文件
     * @return 返回文件上传的结果
     */
    @PostMapping("/file")
    public ResponseEntity<String> upload(@RequestParam("file") MultipartFile file) {
        // 获取文件名，用于后续操作和进度跟踪
        String fileName = file.getOriginalFilename();

        // 获取文件总大小，以字节为单位
        Double totalSize = Double.valueOf(file.getSize());

        // 声明输入流，用于读取上传的文件
        InputStream inputStream = null;

        // 声明输出流，用于将文件写入服务器的指定位置
        OutputStream outputStream = null;

        // 定义缓冲区，每次读取1KB大小的数据块
        byte[] bytes = new byte[1024];

        // 定义读取的字节数
        int read;

        // 用于追踪文件已处理的大小
        Double process = 0.0;

        // 初始化上传进度百分比
        long percent = 0;

        try {
            // 获取文件的输入流，用于读取文件数据
            inputStream = file.getInputStream();

            // 创建文件的输出流，指定上传文件的保存路径和名称
            outputStream = new FileOutputStream(new File("D:/1/文件上传/" + fileName));

            // 循环读取文件的字节流，直到文件数据读取完毕
            while ((read = inputStream.read(bytes)) != -1) {
                // 更新已处理的文件大小
                process += read;

                // 计算当前的上传进度百分比
                long newPercent = (long) (process / totalSize * 100);

                // 仅在进度更新时，才将新的百分比存入进度缓存
                if (newPercent != percent) {
                    percent = newPercent;

                    // 将当前文件的上传进度存储到 progressMap 中，键为文件名
                    progressMap.put(fileName, percent);

                    // 输出当前进度日志，便于调试
                    System.out.println("文件 " + fileName + " 上传进度：" + percent + "%");
                }

                // 将数据块写入输出流（写到服务器上的文件）
                outputStream.write(bytes, 0, read);
            }

        } catch (IOException e) {
            // 如果出现 IO 异常，打印错误堆栈信息
            e.printStackTrace();

            // 返回 HTTP 500 错误，表示文件上传失败
            return ResponseEntity.status(500).body("文件上传失败");
        } finally {
            // 在 finally 块中关闭输入和输出流，确保资源被正确释放

            // 关闭输入流，避免资源泄漏
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace(); // 打印输入流关闭时的异常
            }

            // 关闭输出流，避免资源泄漏
            try {
                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace(); // 打印输出流关闭时的异常
            }

            // 文件上传完成后，将该文件的上传进度信息从缓存中移除
            progressMap.remove(fileName);
        }

        // 返回 HTTP 200 响应，表示文件上传成功
        return ResponseEntity.ok("文件上传成功");
    }

    /**
     * 获取百分比
     * @return
     */
    @GetMapping("/persent")
    public R getPersent(String name) {
        return R.ok().put("data",  CacheUitl.getValue(name) == null? 0 : CacheUitl.getValue(name));
    }
}
